home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / PowerMacOberon feb96 / Source / StyleElems.Mod (.txt) < prev    next >
Oberon Text  |  1995-02-10  |  11KB  |  268 lines

  1. Syntax10.Scn.Fnt
  2. InfoElems
  3. Alloc
  4. Syntax10.Scn.Fnt
  5. StampElems
  6. Alloc
  7. 10 Feb 95
  8. "Title": StyleElems
  9. "Author": CAS
  10. "Abstract": Style Elements extend standard Parcs by adding a name and automatic conformance of 
  11.     equally named parcs within a text. For example, a parc named "heading" may be set to format a 
  12.     section heading. Then, all parcs with that name use and maintain the same format as changes are 
  13.     propagated automatically.
  14.     When copying a style parc from one text to another the behaviour of the copied parc depends on 
  15.     the target text. If it already contains a style with that name, the copied parc will adopt itself to 
  16.     that style. Otherwise, the copied parc defines a new style. Likewise, a style parc may be renamed. 
  17.     If it is renamed to a style that already exists in the containing text, the parc will adopt to that style, 
  18.     while otherwise it introduces a new style.
  19. "Keywords": text editing, style elements
  20. "Version": 1.1
  21. "From":  19-May-92 / 28-Sep-93
  22. "Until": 
  23. "Changes": CS: WriteString and ReadString removed (unnecessary, same as Files.x)
  24. "Hints": Read the Elem.Guide.Text, use the GetSet.Dlg
  25. Syntax10b.Scn.Fnt
  26. Syntax12.Scn.Fnt
  27. Syntax10i.Scn.Fnt
  28. MODULE StyleElems;    (** CAS 19-May-92 / 28-Sep-93 **)    
  29.     IMPORT
  30.         Display, Files, Fonts, Viewers, Texts, Oberon, MenuViewers, TextFrames, ParcElems;
  31.     CONST
  32.         search* = 0; change* = 1; rename* = 2;
  33.         NameFont = "Syntax8.Scn.Fnt";
  34.         rightKey = 0; middleKey = 1; leftKey = 2; cancel = {rightKey, middleKey, leftKey};
  35.         pageBreak = TextFrames.pageBreak;
  36.         unit = TextFrames.Unit;
  37.     TYPE
  38.         Name* = ARRAY 32 OF CHAR;
  39.         Parc* = POINTER TO ParcDesc;
  40.         ParcDesc* = RECORD (TextFrames.ParcDesc)
  41.             name*: Name;
  42.             home: Texts.Text
  43.         END;
  44.         UpdateMsg* = RECORD (Texts.ElemMsg)
  45.             id*: INTEGER;
  46.             pos*: LONGINT;
  47.             name*, newName*: Name;
  48.             parc*: Parc
  49.         END;
  50.         font*: Fonts.Font;
  51.     (* arguments *)
  52.     PROCEDURE MarkedFrame (): TextFrames.Frame;
  53.         VAR v: Viewers.Viewer;
  54.     BEGIN v := Oberon.MarkedViewer();
  55.         IF (v IS MenuViewers.Viewer) & (v.dsc.next IS TextFrames.Frame) THEN
  56.             RETURN v.dsc.next(TextFrames.Frame)
  57.         ELSE RETURN NIL
  58.         END
  59.     END MarkedFrame;
  60.     PROCEDURE FocusFrame (): TextFrames.Frame;
  61.         VAR v: Viewers.Viewer; f: TextFrames.Frame;
  62.     BEGIN v := Oberon.FocusViewer;
  63.         IF (v IS MenuViewers.Viewer) & (v.dsc.next IS TextFrames.Frame) THEN
  64.             f := v.dsc.next(TextFrames.Frame);
  65.             IF f.hasCar THEN RETURN f ELSE RETURN NIL END
  66.         ELSE RETURN NIL
  67.         END
  68.     END FocusFrame;
  69.     PROCEDURE GetMainArg (VAR S: Texts.Scanner);
  70.         (*after command or (^) at selection*)
  71.         VAR text: Texts.Text; beg, end, time: LONGINT;
  72.     BEGIN Texts.Scan(S);
  73.         IF (S.class = Texts.Char) & (S.c = "^") THEN Oberon.GetSelection(text, beg, end, time);
  74.             IF time >= 0 THEN Texts.OpenScanner(S, text, beg); Texts.Scan(S) END
  75.         END;
  76.         IF S.line # 0 THEN S.class := Texts.Inval END
  77.     END GetMainArg;
  78.     (** operations on elements **)
  79.     PROCEDURE Broadcast* (T: Texts.Text; VAR msg: UpdateMsg);
  80.         VAR R: Texts.Reader; e: Texts.Elem;
  81.     BEGIN Texts.OpenReader(R, T, 0); Texts.ReadElem(R);
  82.         WHILE ~R.eot DO e := R.elem; msg.pos := Texts.Pos(R) - 1; Texts.ReadElem(R); e.handle(e, msg) END
  83.     END Broadcast;
  84.     PROCEDURE Search* (T: Texts.Text; VAR name: Name; VAR P: Parc);
  85.         VAR update: UpdateMsg;
  86.     BEGIN update.id := search; update.name := name; update.parc := NIL;
  87.         Broadcast(T, update);
  88.         P := update.parc
  89.     END Search;
  90.     PROCEDURE Synch* (P: Parc; VAR synched: BOOLEAN);
  91.         VAR T: Texts.Text; Q: Parc;
  92.     BEGIN T := Texts.ElemBase(P); synched := FALSE;
  93.         IF (T # NIL) & (P.home # T) THEN Search(T, P.name, Q);
  94.             IF Q # NIL THEN ParcElems.CopyParc(Q, P); EXCL(P.opts, pageBreak); synched := TRUE END;
  95.             P.home := T
  96.         END
  97.     END Synch;
  98.     PROCEDURE ChangeSetting* (P: Parc);
  99.         VAR T: Texts.Text; update: UpdateMsg;
  100.     BEGIN T := Texts.ElemBase(P);
  101.         update.id := change; update.name := P.name; update.parc := P;
  102.         Broadcast(T, update)
  103.     END ChangeSetting;
  104.     PROCEDURE ChangeName* (P: Parc; name: ARRAY OF CHAR; VAR synched: BOOLEAN);
  105.     BEGIN synched := FALSE;
  106.         IF P.name # name THEN COPY(name, P.name); P.home := NIL; Synch(P, synched) END
  107.     END ChangeName;
  108.     PROCEDURE Load* (P: Parc; VAR r: Files.Rider);
  109.     BEGIN ParcElems.LoadParc(P, r); Files.ReadString(r, P.name); P.home := Texts.ElemBase(P)
  110.     END Load;
  111.     PROCEDURE Store* (P: Parc; VAR r: Files.Rider);
  112.         VAR synched: BOOLEAN;
  113.     BEGIN Synch(P, synched); ParcElems.StoreParc(P, r); Files.WriteString(r, P.name)
  114.     END Store;
  115.     PROCEDURE Copy* (SP, DP: Parc);
  116.     BEGIN ParcElems.CopyParc(SP, DP); DP.name := SP.name; DP.home := SP.home
  117.     END Copy;
  118.     PROCEDURE Prepare* (P: Parc; indent, unit: LONGINT);
  119.         VAR synched: BOOLEAN;
  120.     BEGIN Synch(P, synched); ParcElems.Prepare(P, indent, unit);
  121.         IF LONG(font.height + 4) * unit > P.H THEN P.H := LONG(font.height + 4) * unit END
  122.     END Prepare;
  123.     PROCEDURE Width (P: Parc): INTEGER;
  124.         VAR pat: Display.Pattern; i, px, dx, x, y, w, h: INTEGER;
  125.     BEGIN i := 0; px := 0;
  126.         WHILE P.name[i] # 0X DO
  127.             Display.GetChar(font.raster, P.name[i], dx, x, y, w, h, pat); INC(px, dx); INC(i)
  128.         END;
  129.         RETURN px
  130.     END Width;
  131.     PROCEDURE DrawString (P: Parc; col: SHORTINT; x0, y0, bw: INTEGER);
  132.         VAR pat: Display.Pattern; i, dx, x, y, w, h: INTEGER;
  133.     BEGIN i := 0;
  134.         Display.ReplConst(Display.black, x0, y0, bw + 4, font.height, Display.replace); INC(x0, 2); DEC(y0, font.minY);
  135.         WHILE P.name[i] # 0X DO
  136.             Display.GetChar(font.raster, P.name[i], dx, x, y, w, h, pat); INC(i);
  137.             Display.CopyPattern(col, pat, x0 + x, y0 + y, Display.replace); INC(x0, dx)
  138.         END
  139.     END DrawString;
  140.     PROCEDURE Draw* (P: Parc; F: Display.Frame; col: SHORTINT; x0, y0: INTEGER);
  141.         VAR bw: INTEGER;
  142.     BEGIN ParcElems.Draw(P, F, col, x0, y0);
  143.         bw := Width(P); DrawString(P, col, x0 + SHORT(P.W DIV unit) - bw - 20, y0 + 4, bw)
  144.     END Draw;
  145.     PROCEDURE Edit* (P: Parc; F: TextFrames.Frame; pos: LONGINT; x0, y0, x, y: INTEGER; keysum: SET);
  146.     BEGIN
  147.         IF F.showsParcs THEN ParcElems.Edit(P, F, pos, x0, y0, x, y, keysum);
  148.             IF (middleKey IN keysum) & (keysum # cancel) THEN ChangeSetting(P) END
  149.         END
  150.     END Edit;
  151.     PROCEDURE SetAttr* (P: Parc; F: TextFrames.Frame; VAR S: Texts.Scanner; log: Texts.Text);
  152.     BEGIN ParcElems.SetAttr(P, F, unit, S, log); ChangeSetting(P)
  153.     END SetAttr;
  154.     (** handle elements **)
  155.     PROCEDURE Handle* (E: Texts.Elem; VAR msg: Texts.ElemMsg);
  156.         VAR e: Parc; opts: SET; synched: BOOLEAN;
  157.     BEGIN
  158.         WITH E: Parc DO
  159.             IF msg IS TextFrames.DisplayMsg THEN
  160.                 WITH msg: TextFrames.DisplayMsg DO
  161.                     IF msg.prepare THEN Prepare(E, msg.indent, unit)
  162.                     ELSE Draw(E, msg.frame, msg.col, msg.X0, msg.Y0)
  163.                     END
  164.                 END
  165.             ELSIF msg IS Texts.IdentifyMsg THEN
  166.                 WITH msg: Texts.IdentifyMsg DO msg.mod := "StyleElems"; msg.proc := "Alloc" END
  167.             ELSIF msg IS Texts.FileMsg THEN
  168.                 WITH msg: Texts.FileMsg DO
  169.                     IF msg.id = Texts.load THEN Load(E, msg.r)
  170.                     ELSIF msg.id = Texts.store THEN Store(E, msg.r)
  171.                     END
  172.                 END
  173.             ELSIF msg IS Texts.CopyMsg THEN NEW(e); Copy(E, e); msg(Texts.CopyMsg).e := e
  174.             ELSIF msg IS TextFrames.TrackMsg THEN
  175.                 WITH msg: TextFrames.TrackMsg DO
  176.                     Edit(E, msg.frame(TextFrames.Frame), msg.pos, msg.X0, msg.Y0, msg.X, msg.Y, msg.keys)
  177.                 END
  178.             ELSIF msg IS ParcElems.StateMsg THEN
  179.                 WITH msg: ParcElems.StateMsg DO
  180.                     IF msg.id = ParcElems.set THEN SetAttr(E, msg.frame, msg.par, msg.log)
  181.                     ELSE ParcElems.Handle(E, msg)
  182.                     END
  183.                 END
  184.             ELSIF msg IS UpdateMsg THEN
  185.                 WITH msg: UpdateMsg DO
  186.                     IF (msg.id = search) & (msg.parc = NIL) & (E.name = msg.name) & (E.home = Texts.ElemBase(E)) THEN
  187.                         msg.parc := E
  188.                     ELSIF (msg.id = change) & (E.name = msg.name) THEN
  189.                         IF E # msg.parc THEN opts := E.opts;
  190.                             ParcElems.CopyParc(msg.parc, E); E.opts := E.opts - {pageBreak} + opts * {pageBreak}
  191.                         END;
  192.                         ParcElems.ChangedParc(E, msg.pos)
  193.                     ELSIF (msg.id = rename) & (E.name = msg.name) THEN
  194.                         ChangeName(E, msg.newName, synched);
  195.                         IF synched THEN ParcElems.ChangedParc(E, msg.pos)
  196.                         ELSE Texts.ChangeLooks(Texts.ElemBase(E), msg.pos, msg.pos+1, {}, NIL, 0, 0)
  197.                         END
  198.                     END
  199.                 END
  200.             ELSE ParcElems.Handle(E, msg)
  201.             END
  202.         END
  203.     END Handle;
  204.     PROCEDURE Alloc*;
  205.         VAR p: Parc;
  206.     BEGIN NEW(p); p.handle := Handle; Texts.new := p
  207.     END Alloc;
  208.     (** commands **)
  209.     PROCEDURE Insert*;    (** ("^" | name | string) **)
  210.         VAR F: TextFrames.Frame; P: TextFrames.Parc; p: Parc; S: Texts.Scanner; pbeg: LONGINT;
  211.             m: TextFrames.InsertElemMsg;
  212.     BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); GetMainArg(S);
  213.         IF (S.class = Texts.Name) OR (S.class = Texts.String) THEN
  214.             F := FocusFrame();
  215.             IF F # NIL THEN TextFrames.ParcBefore(F.text, F.carloc.pos, P, pbeg)
  216.             ELSE P := TextFrames.defParc
  217.             END;
  218.             NEW(p); ParcElems.CopyParc(P, p);
  219.             p.handle := Handle; COPY(S.s, p.name); p.home := NIL; m.e := p;
  220.             Oberon.FocusViewer.handle(Oberon.FocusViewer, m)
  221.         END
  222.     END Insert;
  223.     PROCEDURE Rename*;    (** ("^" | name | string) ["/s"] **)
  224.         VAR S: Texts.Scanner; F: TextFrames.Frame; P: TextFrames.Parc; p: Parc;
  225.             pbeg: LONGINT; synch, synched: BOOLEAN;
  226.             name: Name;
  227.     BEGIN F := MarkedFrame(); Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); GetMainArg(S);
  228.         IF (F # NIL) & F.hasSel & (F.selbeg.pos + 1 = F.selend.pos)
  229.         & ((S.class = Texts.Name) OR (S.class = Texts.String)) THEN
  230.             TextFrames.ParcBefore(F.text, F.selbeg.pos, P, pbeg);
  231.             IF (P IS Parc) & (pbeg = F.selbeg.pos) & (P(Parc).name # S.s) THEN
  232.                 COPY(S.s, name); Texts.Scan(S);
  233.                 IF (S.class = Texts.Char) & (S.c = "/") & (CAP(S.nextCh) = "S") THEN synch := TRUE
  234.                 ELSE Search(F.text, name, p); synch := p = NIL
  235.                 END;
  236.                 ChangeName(P(Parc), name, synched);
  237.                 IF synched THEN ParcElems.ChangedParc(P, pbeg)
  238.                 ELSE Texts.ChangeLooks(F.text, pbeg, pbeg+1, {}, NIL, 0, 0)
  239.                 END
  240.             END
  241.         END
  242.     END Rename;
  243.     PROCEDURE RenameAll*;    (** ("^" | name | string) ["/s"] **)
  244.         VAR S: Texts.Scanner; F: TextFrames.Frame; P: TextFrames.Parc; p: Parc;
  245.             pbeg: LONGINT; synch: BOOLEAN;
  246.             msg: UpdateMsg; name: Name;
  247.     BEGIN F := MarkedFrame(); Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); GetMainArg(S);
  248.         IF (F # NIL) & F.hasSel & (F.selbeg.pos + 1 = F.selend.pos)
  249.         & ((S.class = Texts.Name) OR (S.class = Texts.String)) THEN
  250.             TextFrames.ParcBefore(F.text, F.selbeg.pos, P, pbeg);
  251.             IF (P IS Parc) & (pbeg = F.selbeg.pos) & (P(Parc).name # S.s) THEN
  252.                 COPY(S.s, name); Texts.Scan(S);
  253.                 IF (S.class = Texts.Char) & (S.c = "/") & (CAP(S.nextCh) = "S") THEN synch := TRUE
  254.                 ELSE Search(F.text, name, p); synch := p = NIL
  255.                 END;
  256.                 IF synch THEN
  257.                     msg.id := rename; msg.name := P(Parc).name; msg.newName := name;
  258.                     Broadcast(F.text, msg)
  259.                 END
  260.             END
  261.         END
  262.     END RenameAll;
  263. BEGIN font := Fonts.This(NameFont)
  264. END StyleElems.
  265.     Write.Open ^    Styles.Text        System.Free StyleElems ~
  266.     StyleElems.Insert ^    StyleElems.Rename ^    StyleElems.RenameAll ^
  267.         "heading"    "sub-heading"    "table A"/s
  268.